/**
 * 
 */
package com.tomagency.cyberlab.server.api;

import java.io.IOException;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.tomagency.cyberlab.server.config.CyberlabConfigProvider;
import com.tomagency.cyberlab.server.config.FileSystemConfig;
import com.tomagency.cyberlab.server.exports.BubuHandler;
import com.tomagency.cyberlab.server.exports.BubuXmlParserResultImpl;
import com.tomagency.cyberlab.server.exports.BubuHandler.BubuStatus;
import com.tomagency.cyberlab.server.util.LoggingUtil;
import com.tomagency.cyberlab.server.util.ServletHelper;

import de.gammadata.business.modelle.BelegDO;
import de.gammadata.communication.modelle.PostingDO;
import de.gammadata.gwt.modelle.Beleg;
import de.gammadata.gwt.modelle.Message.Importance;
import de.gammadata.gwt.modelle.Message.Status;
import de.gammadata.persistence.BelegDAO;
import de.gammadata.persistence.PersistenceManager;


/**
 * @author gfr
 *
 */
@Singleton
public class BubuApiServlet extends HttpServlet {
	
	public static final String OK_RESPONSE = "<xml> <status>ok</status> </xml>";
	public static final String FEHLER_RESPONSE="<xml> <status>error</status> <exception> <error> <code>na</code> <reason>Order nicht gefunden</reason><location></location> </error> </exception> </xml>";
	
	@Inject private LoggingUtil loggingUtil;
	@Inject private FileSystemConfig fsystem;
	@Inject private CyberlabConfigProvider cyberlabConfigProvider;
	@Inject private BubuHandler bubuHandler;
	@Inject private PersistenceManager persistenceManager;
	
	private BelegDAO belegDAO=new BelegDAO();

	/**
	 * 
	 */
	public BubuApiServlet() {
		// TODO Auto-generated constructor stub
	}
	@Override
	public void init(){
		
	}
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
	throws ServletException, IOException {
		processRequest(req,resp);
		
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
	throws ServletException, IOException {
		processRequest(req,resp);
		
	}
	
	private void processRequest(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
		req.setCharacterEncoding("UTF-8");
		
		String responseTxt=FEHLER_RESPONSE;
		
		Enumeration<String> e=req.getParameterNames();
		StringBuilder sb = new StringBuilder();
		while (e.hasMoreElements()){
			
			String name = e.nextElement();
			sb.append(name+"="+req.getParameter(name)+"\n");
		}
		Logger logger = loggingUtil.getApiLogger(this.getClass().getName());
		logger.info("-----BubuApiServlet http-get-req-start-----");
		logger.info("remote-ip="+req.getRemoteAddr());
		
		
		  Enumeration headerNames = req.getHeaderNames();
		    while(headerNames.hasMoreElements()) {
		      String headerName = (String)headerNames.nextElement();
		      logger.info(headerName+"="+req.getHeader(headerName));
		    }
		   
		    
		    logger.info("url="+req.getRequestURL()+"\n"+sb);
		    logger.info("sessionid="+req.getSession().getId());
		    logger.info("-----BubuApiServlet: http-get-req-end-----");
		    
		    String xml=req.getParameter("serializedData");
		    String cmd =req.getParameter("cmd");
		    if (cmd!=null&&cmd.equalsIgnoreCase("orderstatus")&&xml!=null&&xml.length()>10){
		    	
		    	BubuXmlParserResultImpl result=bubuHandler.processBubuXmlResponse(ServletHelper.XML_UTF8_HEADER+xml);
		    	logger.info("bubu response geparst, resultOk= "+result.isOk());
		    	/*
		    	 * Ergebnis verarbeiten
		    	 * result.getStatusList() hat für jede belegNummer einen Status text-Eintrag
		    	 * dieser Eintrag wird als Posting (subject) dem Beleg zugeordnet.
		    	 */
		    	if (result.isOk()&&result.getStatusList()!=null&&result.getStatusList().size()>0){
		    		
		    		EntityManager em=persistenceManager.getEntityManager();
		    		
		    		
		    		try {
//		    			int belegNr=0;
		    			
		    			
		    			
//		    			Set<Integer> set=result.getStatusList().keySet();
//		    			for (Integer belegNr:set){
//		    				String status=result.getStatusList().get(belegNr);
	    				for (BubuStatus bs : result.getStatusList()){
	    				//Beleg suchen
	    					int belegNr = bs.getBelegNummer();
	    					EntityTransaction tx=em.getTransaction();
	    					List<BelegDO> belegListe = belegDAO.findByNummer(belegNr, em);
	    					
		    				if (belegListe!=null && belegListe.size()>0){
		    					
								BelegDO beleg = belegListe.get(0);
								logger.info("processRequest() bearbeite Beleg: "+beleg.getNummer()+ " Status: "+beleg.getStatus());
								tx.begin();
								PostingDO posting = new PostingDO();
								posting.setDate(new Date());
								String status = String.format("%1$d Orderstatus = %2$s Jobstatus = %3$s", bs.getBelegNummer(),bs.getOrderStatus(),bs.getJobStatus());
								posting.setSubject(status);
								posting.setImportance(Importance.NORMAL);
								posting.setStatus(Status.NEU);
								posting.setProjekt(beleg.getProject());
								beleg.addMessage(posting);
								logger.info("processRequest() neues Posting erzeugt: "+status);
								/*
								 * Beleg Status lt. Meldung anpassen
								 */
								
								if ((bs.getOrderStatus()!=null && bs.getJobStatus()!=null)
										&&(
												!( Beleg.STATUS_ABGESCHLOSSEN.equalsIgnoreCase(beleg.getStatus())
												||(Beleg.STATUS_STORNO.equalsIgnoreCase(beleg.getStatus()))
												||(Beleg.STATUS_ARCHIV.equalsIgnoreCase(beleg.getStatus())) )
												)){
									//zuerst Fehler Abfragen
									if (BubuStatus.ORDERSTATUS_CANCELLED.equalsIgnoreCase(bs.getOrderStatus())
											||BubuStatus.JOBSTATUS_ERROR.equalsIgnoreCase(bs.getJobStatus())
											||BubuStatus.JOBSTATUS_GELÖSCHT.equalsIgnoreCase(bs.getJobStatus())){
										beleg.setStatus(Beleg.STATUS_ACHTUNG);
										logger.info("processRequest() setze Beleg "+beleg.getNummer()+" auf Status: "+beleg.getStatus());
									}
									else{
										//ist schon fertig oder geliefert gesetzt
										if (!(Beleg.STATUS_REINKOMMEND.equalsIgnoreCase(beleg.getStatus())
												||Beleg.STATUS_PRODUZIERT.equalsIgnoreCase(beleg.getStatus()))){
											//Abfrage Produktions Stati
											if (BubuStatus.ORDERSTATUS_PRODUCTION.equalsIgnoreCase(bs.getOrderStatus())){
												if (BubuStatus.JOBSTATUS_FERTIG.equalsIgnoreCase(bs.getJobStatus())){
													beleg.setStatus(Beleg.STATUS_PRODUZIERT);
													logger.info("processRequest() setze Beleg "+beleg.getNummer()+" auf Status: "+beleg.getStatus());
												}
												else if(BubuStatus.JOBSTATUS_AUSGELIEFERT.equalsIgnoreCase(bs.getJobStatus())){
													beleg.setStatus(Beleg.STATUS_REINKOMMEND);
													logger.info("processRequest() setze Beleg "+beleg.getNummer()+" auf Status: "+beleg.getStatus());
												}
												else{
													beleg.setStatus(Beleg.STATUS_INARBEIT);
													logger.info("processRequest() setze Beleg "+beleg.getNummer()+" auf Status: "+beleg.getStatus());
												}
											} //Ende Prod Stati
										}
										if (BubuStatus.JOBSTATUS_AUSGELIEFERT.equalsIgnoreCase(bs.getJobStatus())
												||BubuStatus.ORDERSTATUS_DISPATCHED.equalsIgnoreCase(bs.getOrderStatus())){
											beleg.setStatus(Beleg.STATUS_REINKOMMEND);
											logger.info("processRequest() setze Beleg "+beleg.getNummer()+" auf Status: "+beleg.getStatus());
										}
									}
									
									
									
								}
								

								try {
									beleg=belegDAO.storeEntity(beleg, em);
									tx.commit();
									responseTxt=OK_RESPONSE;
								} catch (Exception e1) {
									logger.error("processRequest() Fehler bei storeEntity ",e1);
								}
																
								

							}
							else{
								logger.error("Fehler, bubu response, Beleg nicht gefunden Nummer= "+belegNr);
							}
		    				
		    			}
						
					} catch (Exception e1) {
						logger.error("Fehler beim Verarbeiten bubu response",e1);
					}

					em.close();
		    		
		    		
		    	}
		    	else{
		    		//log
		    		logger.error("Fehler, bubu response Fehler beim Parsen  serializedData=  \n"+xml);
		    	}
		    	
		    	
		    }
		    else{
		    	logger.error("bubu response falsch oder zu kurz, cmd="+cmd+", serializedData= "+xml);
		    }
		    
		    ServletHelper.sendResponse(resp,responseTxt, "text/plain", "UTF-8");
		    
	}
	
	

}
